/* SPDX-License-Identifier: GPL-2.0 */
/*
 * SpacemiT K1 Ethernet hardware definitions
 *
 * Copyright (C) 2023-2025 SpacemiT (Hangzhou) Technology Co. Ltd
 * Copyright (C) 2025 Vivian Wang <wangruikang@iscas.ac.cn>
 */

#ifndef _K1_EMAC_H_
#define _K1_EMAC_H_

#include <linux/stddef.h>

/* APMU syscon registers */

#define APMU_EMAC_CTRL_REG				0x0

#define PHY_INTF_RGMII					BIT(2)

/*
 * Only valid for RMII mode
 * 0: Ref clock from External PHY
 * 1: Ref clock from SoC
 */
#define REF_CLK_SEL					BIT(3)

/*
 * Function clock select
 * 0: 208 MHz
 * 1: 312 MHz
 */
#define FUNC_CLK_SEL					BIT(4)

/* Only valid for RMII, invert TX clk */
#define RMII_TX_CLK_SEL					BIT(6)

/* Only valid for RMII, invert RX clk */
#define RMII_RX_CLK_SEL					BIT(7)

/*
 * Only valid for RGMII
 * 0: TX clk from RX clk
 * 1: TX clk from SoC
 */
#define RGMII_TX_CLK_SEL				BIT(8)

#define PHY_IRQ_EN					BIT(12)
#define AXI_SINGLE_ID					BIT(13)

#define APMU_EMAC_DLINE_REG				0x4

#define EMAC_RX_DLINE_EN				BIT(0)
#define EMAC_RX_DLINE_STEP_MASK				GENMASK(5, 4)
#define EMAC_RX_DLINE_CODE_MASK				GENMASK(15, 8)

#define EMAC_TX_DLINE_EN				BIT(16)
#define EMAC_TX_DLINE_STEP_MASK				GENMASK(21, 20)
#define EMAC_TX_DLINE_CODE_MASK				GENMASK(31, 24)

#define EMAC_DLINE_STEP_15P6				0  /* 15.6 ps/step */
#define EMAC_DLINE_STEP_24P4				1  /* 24.4 ps/step */
#define EMAC_DLINE_STEP_29P7				2  /* 29.7 ps/step */
#define EMAC_DLINE_STEP_35P1				3  /* 35.1 ps/step */

/* DMA register set */
#define DMA_CONFIGURATION				0x0000
#define DMA_CONTROL					0x0004
#define DMA_STATUS_IRQ					0x0008
#define DMA_INTERRUPT_ENABLE				0x000c

#define DMA_TRANSMIT_AUTO_POLL_COUNTER			0x0010
#define DMA_TRANSMIT_POLL_DEMAND			0x0014
#define DMA_RECEIVE_POLL_DEMAND				0x0018

#define DMA_TRANSMIT_BASE_ADDRESS			0x001c
#define DMA_RECEIVE_BASE_ADDRESS			0x0020
#define DMA_MISSED_FRAME_COUNTER			0x0024
#define DMA_STOP_FLUSH_COUNTER				0x0028

#define DMA_RECEIVE_IRQ_MITIGATION_CTRL			0x002c

#define DMA_CURRENT_TRANSMIT_DESCRIPTOR_POINTER		0x0030
#define DMA_CURRENT_TRANSMIT_BUFFER_POINTER		0x0034
#define DMA_CURRENT_RECEIVE_DESCRIPTOR_POINTER		0x0038
#define DMA_CURRENT_RECEIVE_BUFFER_POINTER		0x003c

/* MAC Register set */
#define MAC_GLOBAL_CONTROL				0x0100
#define MAC_TRANSMIT_CONTROL				0x0104
#define MAC_RECEIVE_CONTROL				0x0108
#define MAC_MAXIMUM_FRAME_SIZE				0x010c
#define MAC_TRANSMIT_JABBER_SIZE			0x0110
#define MAC_RECEIVE_JABBER_SIZE				0x0114
#define MAC_ADDRESS_CONTROL				0x0118
#define MAC_MDIO_CLK_DIV				0x011c
#define MAC_ADDRESS1_HIGH				0x0120
#define MAC_ADDRESS1_MED				0x0124
#define MAC_ADDRESS1_LOW				0x0128
#define MAC_ADDRESS2_HIGH				0x012c
#define MAC_ADDRESS2_MED				0x0130
#define MAC_ADDRESS2_LOW				0x0134
#define MAC_ADDRESS3_HIGH				0x0138
#define MAC_ADDRESS3_MED				0x013c
#define MAC_ADDRESS3_LOW				0x0140
#define MAC_ADDRESS4_HIGH				0x0144
#define MAC_ADDRESS4_MED				0x0148
#define MAC_ADDRESS4_LOW				0x014c
#define MAC_MULTICAST_HASH_TABLE1			0x0150
#define MAC_MULTICAST_HASH_TABLE2			0x0154
#define MAC_MULTICAST_HASH_TABLE3			0x0158
#define MAC_MULTICAST_HASH_TABLE4			0x015c
#define MAC_FC_CONTROL					0x0160
#define MAC_FC_PAUSE_FRAME_GENERATE			0x0164
#define MAC_FC_SOURCE_ADDRESS_HIGH			0x0168
#define MAC_FC_SOURCE_ADDRESS_MED			0x016c
#define MAC_FC_SOURCE_ADDRESS_LOW			0x0170
#define MAC_FC_DESTINATION_ADDRESS_HIGH			0x0174
#define MAC_FC_DESTINATION_ADDRESS_MED			0x0178
#define MAC_FC_DESTINATION_ADDRESS_LOW			0x017c
#define MAC_FC_PAUSE_TIME_VALUE				0x0180
#define MAC_FC_HIGH_PAUSE_TIME				0x0184
#define MAC_FC_LOW_PAUSE_TIME				0x0188
#define MAC_FC_PAUSE_HIGH_THRESHOLD			0x018c
#define MAC_FC_PAUSE_LOW_THRESHOLD			0x0190
#define MAC_MDIO_CONTROL				0x01a0
#define MAC_MDIO_DATA					0x01a4
#define MAC_RX_STATCTR_CONTROL				0x01a8
#define MAC_RX_STATCTR_DATA_HIGH			0x01ac
#define MAC_RX_STATCTR_DATA_LOW				0x01b0
#define MAC_TX_STATCTR_CONTROL				0x01b4
#define MAC_TX_STATCTR_DATA_HIGH			0x01b8
#define MAC_TX_STATCTR_DATA_LOW				0x01bc
#define MAC_TRANSMIT_FIFO_ALMOST_FULL			0x01c0
#define MAC_TRANSMIT_PACKET_START_THRESHOLD		0x01c4
#define MAC_RECEIVE_PACKET_START_THRESHOLD		0x01c8
#define MAC_STATUS_IRQ					0x01e0
#define MAC_INTERRUPT_ENABLE				0x01e4

/* Used for register dump */
#define EMAC_DMA_REG_CNT		16
#define EMAC_MAC_REG_CNT		124

/* DMA_CONFIGURATION (0x0000) */

/*
 * 0-DMA controller in normal operation mode,
 * 1-DMA controller reset to default state,
 * clearing all internal state information
 */
#define MREGBIT_SOFTWARE_RESET				BIT(0)

#define MREGBIT_BURST_1WORD				BIT(1)
#define MREGBIT_BURST_2WORD				BIT(2)
#define MREGBIT_BURST_4WORD				BIT(3)
#define MREGBIT_BURST_8WORD				BIT(4)
#define MREGBIT_BURST_16WORD				BIT(5)
#define MREGBIT_BURST_32WORD				BIT(6)
#define MREGBIT_BURST_64WORD				BIT(7)
#define MREGBIT_BURST_LENGTH				GENMASK(7, 1)
#define MREGBIT_DESCRIPTOR_SKIP_LENGTH			GENMASK(12, 8)

/* For Receive and Transmit DMA operate in Big-Endian mode for Descriptors. */
#define MREGBIT_DESCRIPTOR_BYTE_ORDERING		BIT(13)

#define MREGBIT_BIG_LITLE_ENDIAN			BIT(14)
#define MREGBIT_TX_RX_ARBITRATION			BIT(15)
#define MREGBIT_WAIT_FOR_DONE				BIT(16)
#define MREGBIT_STRICT_BURST				BIT(17)
#define MREGBIT_DMA_64BIT_MODE				BIT(18)

/* DMA_CONTROL (0x0004) */
#define MREGBIT_START_STOP_TRANSMIT_DMA			BIT(0)
#define MREGBIT_START_STOP_RECEIVE_DMA			BIT(1)

/* DMA_STATUS_IRQ (0x0008) */
#define MREGBIT_TRANSMIT_TRANSFER_DONE_IRQ		BIT(0)
#define MREGBIT_TRANSMIT_DES_UNAVAILABLE_IRQ		BIT(1)
#define MREGBIT_TRANSMIT_DMA_STOPPED_IRQ		BIT(2)
#define MREGBIT_RECEIVE_TRANSFER_DONE_IRQ		BIT(4)
#define MREGBIT_RECEIVE_DES_UNAVAILABLE_IRQ		BIT(5)
#define MREGBIT_RECEIVE_DMA_STOPPED_IRQ			BIT(6)
#define MREGBIT_RECEIVE_MISSED_FRAME_IRQ		BIT(7)
#define MREGBIT_MAC_IRQ					BIT(8)
#define MREGBIT_TRANSMIT_DMA_STATE			GENMASK(18, 16)
#define MREGBIT_RECEIVE_DMA_STATE			GENMASK(23, 20)

/* DMA_INTERRUPT_ENABLE (0x000c) */
#define MREGBIT_TRANSMIT_TRANSFER_DONE_INTR_ENABLE	BIT(0)
#define MREGBIT_TRANSMIT_DES_UNAVAILABLE_INTR_ENABLE	BIT(1)
#define MREGBIT_TRANSMIT_DMA_STOPPED_INTR_ENABLE	BIT(2)
#define MREGBIT_RECEIVE_TRANSFER_DONE_INTR_ENABLE	BIT(4)
#define MREGBIT_RECEIVE_DES_UNAVAILABLE_INTR_ENABLE	BIT(5)
#define MREGBIT_RECEIVE_DMA_STOPPED_INTR_ENABLE		BIT(6)
#define MREGBIT_RECEIVE_MISSED_FRAME_INTR_ENABLE	BIT(7)
#define MREGBIT_MAC_INTR_ENABLE				BIT(8)

/* DMA_RECEIVE_IRQ_MITIGATION_CTRL (0x002c) */
#define MREGBIT_RECEIVE_IRQ_FRAME_COUNTER_MASK		GENMASK(7, 0)
#define MREGBIT_RECEIVE_IRQ_TIMEOUT_COUNTER_MASK	GENMASK(27, 8)
#define MREGBIT_RECEIVE_IRQ_FRAME_COUNTER_MODE		BIT(30)
#define MREGBIT_RECEIVE_IRQ_MITIGATION_ENABLE		BIT(31)

/* MAC_GLOBAL_CONTROL (0x0100) */
#define MREGBIT_SPEED					GENMASK(1, 0)
#define MREGBIT_SPEED_10M				0x0
#define MREGBIT_SPEED_100M				BIT(0)
#define MREGBIT_SPEED_1000M				BIT(1)
#define MREGBIT_FULL_DUPLEX_MODE			BIT(2)
#define MREGBIT_RESET_RX_STAT_COUNTERS			BIT(3)
#define MREGBIT_RESET_TX_STAT_COUNTERS			BIT(4)
#define MREGBIT_UNICAST_WAKEUP_MODE			BIT(8)
#define MREGBIT_MAGIC_PACKET_WAKEUP_MODE		BIT(9)

/* MAC_TRANSMIT_CONTROL (0x0104) */
#define MREGBIT_TRANSMIT_ENABLE				BIT(0)
#define MREGBIT_INVERT_FCS				BIT(1)
#define MREGBIT_DISABLE_FCS_INSERT			BIT(2)
#define MREGBIT_TRANSMIT_AUTO_RETRY			BIT(3)
#define MREGBIT_IFG_LEN					GENMASK(6, 4)
#define MREGBIT_PREAMBLE_LENGTH				GENMASK(9, 7)

/* MAC_RECEIVE_CONTROL (0x0108) */
#define MREGBIT_RECEIVE_ENABLE				BIT(0)
#define MREGBIT_DISABLE_FCS_CHECK			BIT(1)
#define MREGBIT_STRIP_FCS				BIT(2)
#define MREGBIT_STORE_FORWARD				BIT(3)
#define MREGBIT_STATUS_FIRST				BIT(4)
#define MREGBIT_PASS_BAD_FRAMES				BIT(5)
#define MREGBIT_ACOOUNT_VLAN				BIT(6)

/* MAC_MAXIMUM_FRAME_SIZE (0x010c) */
#define MREGBIT_MAX_FRAME_SIZE				GENMASK(13, 0)

/* MAC_TRANSMIT_JABBER_SIZE (0x0110) */
#define MREGBIT_TRANSMIT_JABBER_SIZE			GENMASK(15, 0)

/* MAC_RECEIVE_JABBER_SIZE (0x0114) */
#define MREGBIT_RECEIVE_JABBER_SIZE			GENMASK(15, 0)

/* MAC_ADDRESS_CONTROL (0x0118) */
#define MREGBIT_MAC_ADDRESS1_ENABLE			BIT(0)
#define MREGBIT_MAC_ADDRESS2_ENABLE			BIT(1)
#define MREGBIT_MAC_ADDRESS3_ENABLE			BIT(2)
#define MREGBIT_MAC_ADDRESS4_ENABLE			BIT(3)
#define MREGBIT_INVERSE_MAC_ADDRESS1_ENABLE		BIT(4)
#define MREGBIT_INVERSE_MAC_ADDRESS2_ENABLE		BIT(5)
#define MREGBIT_INVERSE_MAC_ADDRESS3_ENABLE		BIT(6)
#define MREGBIT_INVERSE_MAC_ADDRESS4_ENABLE		BIT(7)
#define MREGBIT_PROMISCUOUS_MODE			BIT(8)

/* MAC_FC_CONTROL (0x0160) */
#define MREGBIT_FC_DECODE_ENABLE			BIT(0)
#define MREGBIT_FC_GENERATION_ENABLE			BIT(1)
#define MREGBIT_AUTO_FC_GENERATION_ENABLE		BIT(2)
#define MREGBIT_MULTICAST_MODE				BIT(3)
#define MREGBIT_BLOCK_PAUSE_FRAMES			BIT(4)

/* MAC_FC_PAUSE_FRAME_GENERATE (0x0164) */
#define MREGBIT_GENERATE_PAUSE_FRAME			BIT(0)

/* MAC_FC_PAUSE_TIME_VALUE (0x0180) */
#define MREGBIT_MAC_FC_PAUSE_TIME			GENMASK(15, 0)

/* MAC_MDIO_CONTROL (0x01a0) */
#define MREGBIT_PHY_ADDRESS				GENMASK(4, 0)
#define MREGBIT_REGISTER_ADDRESS			GENMASK(9, 5)
#define MREGBIT_MDIO_READ_WRITE				BIT(10)
#define MREGBIT_START_MDIO_TRANS			BIT(15)

/* MAC_MDIO_DATA (0x01a4) */
#define MREGBIT_MDIO_DATA				GENMASK(15, 0)

/* MAC_RX_STATCTR_CONTROL (0x01a8) */
#define MREGBIT_RX_COUNTER_NUMBER			GENMASK(4, 0)
#define MREGBIT_START_RX_COUNTER_READ			BIT(15)

/* MAC_RX_STATCTR_DATA_HIGH (0x01ac) */
#define MREGBIT_RX_STATCTR_DATA_HIGH			GENMASK(15, 0)
/* MAC_RX_STATCTR_DATA_LOW (0x01b0) */
#define MREGBIT_RX_STATCTR_DATA_LOW			GENMASK(15, 0)

/* MAC_TX_STATCTR_CONTROL (0x01b4) */
#define MREGBIT_TX_COUNTER_NUMBER			GENMASK(4, 0)
#define MREGBIT_START_TX_COUNTER_READ			BIT(15)

/* MAC_TX_STATCTR_DATA_HIGH (0x01b8) */
#define MREGBIT_TX_STATCTR_DATA_HIGH			GENMASK(15, 0)
/* MAC_TX_STATCTR_DATA_LOW (0x01bc) */
#define MREGBIT_TX_STATCTR_DATA_LOW			GENMASK(15, 0)

/* MAC_TRANSMIT_FIFO_ALMOST_FULL (0x01c0) */
#define MREGBIT_TX_FIFO_AF				GENMASK(13, 0)

/* MAC_TRANSMIT_PACKET_START_THRESHOLD (0x01c4) */
#define MREGBIT_TX_PACKET_START_THRESHOLD		GENMASK(13, 0)

/* MAC_RECEIVE_PACKET_START_THRESHOLD (0x01c8) */
#define MREGBIT_RX_PACKET_START_THRESHOLD		GENMASK(13, 0)

/* MAC_STATUS_IRQ (0x01e0) */
#define MREGBIT_MAC_UNDERRUN_IRQ			BIT(0)
#define MREGBIT_MAC_JABBER_IRQ				BIT(1)

/* MAC_INTERRUPT_ENABLE (0x01e4) */
#define MREGBIT_MAC_UNDERRUN_INTERRUPT_ENABLE		BIT(0)
#define MREGBIT_JABBER_INTERRUPT_ENABLE			BIT(1)

/* RX DMA descriptor */

#define RX_DESC_0_FRAME_PACKET_LENGTH_MASK		GENMASK(13, 0)
#define RX_DESC_0_FRAME_ALIGN_ERR			BIT(14)
#define RX_DESC_0_FRAME_RUNT				BIT(15)
#define RX_DESC_0_FRAME_ETHERNET_TYPE			BIT(16)
#define RX_DESC_0_FRAME_VLAN				BIT(17)
#define RX_DESC_0_FRAME_MULTICAST			BIT(18)
#define RX_DESC_0_FRAME_BROADCAST			BIT(19)
#define RX_DESC_0_FRAME_CRC_ERR				BIT(20)
#define RX_DESC_0_FRAME_MAX_LEN_ERR			BIT(21)
#define RX_DESC_0_FRAME_JABBER_ERR			BIT(22)
#define RX_DESC_0_FRAME_LENGTH_ERR			BIT(23)
#define RX_DESC_0_FRAME_MAC_ADDR1_MATCH			BIT(24)
#define RX_DESC_0_FRAME_MAC_ADDR2_MATCH			BIT(25)
#define RX_DESC_0_FRAME_MAC_ADDR3_MATCH			BIT(26)
#define RX_DESC_0_FRAME_MAC_ADDR4_MATCH			BIT(27)
#define RX_DESC_0_FRAME_PAUSE_CTRL			BIT(28)
#define RX_DESC_0_LAST_DESCRIPTOR			BIT(29)
#define RX_DESC_0_FIRST_DESCRIPTOR			BIT(30)
#define RX_DESC_0_OWN					BIT(31)

#define RX_DESC_1_BUFFER_SIZE_1_MASK			GENMASK(11, 0)
#define RX_DESC_1_BUFFER_SIZE_2_MASK			GENMASK(23, 12)
							/* [24] reserved */
#define RX_DESC_1_SECOND_ADDRESS_CHAINED		BIT(25)
#define RX_DESC_1_END_RING				BIT(26)
							/* [29:27] reserved */
#define RX_DESC_1_RX_TIMESTAMP				BIT(30)
#define RX_DESC_1_PTP_PKT				BIT(31)

/* TX DMA descriptor */

							/* [29:0] unused */
#define TX_DESC_0_TX_TIMESTAMP				BIT(30)
#define TX_DESC_0_OWN					BIT(31)

#define TX_DESC_1_BUFFER_SIZE_1_MASK			GENMASK(11, 0)
#define TX_DESC_1_BUFFER_SIZE_2_MASK			GENMASK(23, 12)
#define TX_DESC_1_FORCE_EOP_ERROR			BIT(24)
#define TX_DESC_1_SECOND_ADDRESS_CHAINED		BIT(25)
#define TX_DESC_1_END_RING				BIT(26)
#define TX_DESC_1_DISABLE_PADDING			BIT(27)
#define TX_DESC_1_ADD_CRC_DISABLE			BIT(28)
#define TX_DESC_1_FIRST_SEGMENT				BIT(29)
#define TX_DESC_1_LAST_SEGMENT				BIT(30)
#define TX_DESC_1_INTERRUPT_ON_COMPLETION		BIT(31)

struct emac_desc {
	u32 desc0;
	u32 desc1;
	u32 buffer_addr_1;
	u32 buffer_addr_2;
};

/* Keep stats in this order, index used for accessing hardware */

union emac_hw_tx_stats {
	struct individual_tx_stats {
		u64 tx_ok_pkts;
		u64 tx_total_pkts;
		u64 tx_ok_bytes;
		u64 tx_err_pkts;
		u64 tx_singleclsn_pkts;
		u64 tx_multiclsn_pkts;
		u64 tx_lateclsn_pkts;
		u64 tx_excessclsn_pkts;
		u64 tx_unicast_pkts;
		u64 tx_multicast_pkts;
		u64 tx_broadcast_pkts;
		u64 tx_pause_pkts;
	} stats;

	u64 array[sizeof(struct individual_tx_stats) / sizeof(u64)];
};

union emac_hw_rx_stats {
	struct individual_rx_stats {
		u64 rx_ok_pkts;
		u64 rx_total_pkts;
		u64 rx_crc_err_pkts;
		u64 rx_align_err_pkts;
		u64 rx_err_total_pkts;
		u64 rx_ok_bytes;
		u64 rx_total_bytes;
		u64 rx_unicast_pkts;
		u64 rx_multicast_pkts;
		u64 rx_broadcast_pkts;
		u64 rx_pause_pkts;
		u64 rx_len_err_pkts;
		u64 rx_len_undersize_pkts;
		u64 rx_len_oversize_pkts;
		u64 rx_len_fragment_pkts;
		u64 rx_len_jabber_pkts;
		u64 rx_64_pkts;
		u64 rx_65_127_pkts;
		u64 rx_128_255_pkts;
		u64 rx_256_511_pkts;
		u64 rx_512_1023_pkts;
		u64 rx_1024_1518_pkts;
		u64 rx_1519_plus_pkts;
		u64 rx_drp_fifo_full_pkts;
		u64 rx_truncate_fifo_full_pkts;
	} stats;

	u64 array[sizeof(struct individual_rx_stats) / sizeof(u64)];
};

#endif /* _K1_EMAC_H_ */
